home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_07_03 / v7n3061a.txt < prev    next >
Text File  |  1989-01-16  |  17KB  |  463 lines

  1. Listing1
  2.  
  3.  
  4. /* define WORD to be signed sixteen bit integer                         */
  5. #ifdef MEGAMAX
  6. #define WORD int
  7. #else
  8. #define WORD short
  9. #endif
  10. typedef struct 
  11.     {
  12.     WORD activation;        /* activation of neuron for feedforward     */
  13.     WORD errors;            /* sum of errors from feedback              */
  14.     } NEURON;
  15.  
  16. #define NEURON_SIZE 4         /* sizeof(NEURON) for assembler           */ 
  17. #define O_ERROR 2             /* offset of neuron.errors for assembler  */ 
  18. #define ACTIVATION_SHIFT 7    /* units of 1/128: 2**-7                  */ 
  19. #define RATE_SHIFT       7    /* units of 1/128: 2**-7                  */
  20.  
  21.  
  22. Listing2
  23.  
  24.  
  25. typedef WORD SYNAPSE;
  26. #define MAX_SYNAPSE 32767
  27. #define SYNAPSE_SHIFT 10    /* units of 1/1024: 2**-10                  */
  28.  
  29. typedef struct layer
  30.     {
  31.     struct layer *prev_layer;   /* pointer to previous layer, if any    */
  32.     int n_inputs;           /* number of input neurons                  */
  33.     NEURON *inputs;         /* same address as outputs of previous layer*/
  34.     SYNAPSE *synapses;      /* synapses[n_inputs][n_outputs]            */
  35.     SYNAPSE *history;       /* previous values for use in learning      */
  36.     char rate;              /* learning rate, larger values learn faster*/
  37.     char momentum;          /* learning momentum in powers of two, 0 to 7 */
  38.     int n_outputs;          /* number of output neurons                 */
  39.     NEURON *outputs;        /* same address as inputs of next layer     */
  40.     struct layer *next_layer;   /* pointer to next layer, if any        */
  41.     } LAYER;
  42.  
  43. typedef struct 
  44.     {
  45.     LAYER *first_layer;
  46.     LAYER *last_layer;
  47.     } NETWORK;
  48.  
  49.  
  50.  
  51. Listing3
  52.  
  53.  
  54. transfer(n_inputs, inputs, output, synapses)
  55. register int n_inputs;      /* number of input neurons                  */
  56. register NEURON *inputs;    /* vector of input neurons                  */
  57. NEURON *output;             /* output neuron                            */
  58. register SYNAPSE *synapses; /* vector of synapses on                    */
  59.     {
  60.     register long sum = 0;  /* for accumulating inputs                  */
  61.     long i;                 /* for intermediate                         */
  62.  
  63.     /* feed input activation forward through synapses by accumulating
  64.     products */
  65. #ifndef MEGAMAX
  66.  
  67.     while (--n_inputs >= 0)
  68.         sum += (long) * synapses++*(inputs++)->activation;
  69.  
  70. #else                       /* use Megamax inline assembly for Motorola */
  71.     asm
  72.         {
  73.         bra test
  74.     loop:
  75.         ;
  76.         while (--n_inputs >= 0)
  77.             move.w(synapses) + , D0;
  78.         D0 = *synapses++muls(inputs), D0;
  79.         D0 *= input->activation addq.l#NEURON_SIZE, inputs;
  80.         input++add.l D0, sum;
  81.         sum += D0
  82.     test:
  83.         dbf n_inputs, loop
  84.         }
  85. #endif
  86.  
  87.     /* limit activation overload with log if below -100 or above 100)   */
  88.     if (sum > 0)
  89.         {
  90.         sum += 1 << SYNAPSE_SHIFT - 1;  /* round sum                    */
  91.         sum >>= SYNAPSE_SHIFT;  /* shift sum back into range            */
  92.         if (sum > 100)      /* sum = 100 + log2(sum-100)                */
  93.             for (i = sum, sum = 100; (i >>= 1) >= 100; sum++)
  94.                 ;
  95.         }
  96.     else if (sum < 0)
  97.         {
  98.         sum -= 1 << SYNAPSE_SHIFT - 1;  /* round sum                    */
  99.         sum >>= SYNAPSE_SHIFT;  /* shift sum back into range            */
  100.         if (sum < -100)     /* sum = -100 - log2(-sum-100)              */
  101.             for (i = -sum, sum = -100; (i >>= 1) >= 100; sum--)
  102.                 ;
  103.         }
  104.     output->activation = sum;
  105.     }
  106.  
  107. Listing4
  108.  
  109.  
  110. error(n_inputs, inputs, output, synapses, history, rate, momentum)
  111. register int n_inputs;      /* number of input neurons                  */
  112. register NEURON *inputs;    /* vector of input neurons                  */
  113. NEURON *output;             /* output neuron                            */
  114. register SYNAPSE *synapses; /* vector of synapses on output             */
  115. SYNAPSE *history;           /* vector of synapse history                */
  116. int rate;                   /* transfer learning rate                   */
  117. int momentum;               /* if true use synapse history              */
  118.     {
  119.     WORD error;             /* correction error for synapse             */
  120.     long weight;            /* synapse weight                           */
  121.     long feedback;          /* amount to feedback to previous layer     */
  122.     long delta;             /* amount to change synapse weight          */
  123.  
  124.     /* amount of left shift to bring feedback and delta back into proper
  125.     range */
  126. #define FEEDBACK_SHIFT \
  127.         SYNAPSE_SHIFT+ACTIVATION_SHIFT+RATE_SHIFT-ACTIVATION_SHIFT
  128.             
  129. #define DELTA_SHIFT \
  130.         ACTIVATION_SHIFT+ACTIVATION_SHIFT+RATE_SHIFT-SYNAPSE_SHIFT
  131.     
  132.  
  133.     /* get error, factor in derivative of log limit function if overload*/
  134.     error = output->errors;
  135.     if (output->activation > 100)
  136.         error = (error * 100) / output->activation;
  137.     else if (output->activation < -100)
  138.         error = (error * 100) / output->activation;
  139.     error *= rate;          /* error proportional to learning rate      */
  140.  
  141. #ifndef MEGAMAX
  142.     while (--n_inputs >= 0) /* calculate new synapse weights:           */
  143.         {
  144.         weight = *synapses; /*   get weight from synapse                */
  145.         feedback = weight;  /*   feedback proportional to weight        */
  146.         feedback *= error;  /*   feedback proportional to error         */
  147.         feedback >>= FEEDBACK_SHIFT;    /*   shift feedback into range of
  148.                                         errors                          */
  149.         inputs->errors += feedback; /*   feedback to input errors       */
  150.         delta = inputs->activation; /*   delta proportional to input    */
  151.         inputs++;           /*   next input                             */
  152.         delta *= error;     /*   delta proportional to error            */
  153.         delta >>= DELTA_SHIFT;  /*   shift delta into range of weight   */
  154.         if (momentum)
  155.             {
  156.             delta += *history;  /*   add momentum to delta              */
  157.             *history++ = (SYNAPSE)delta;    /*   save delta for next
  158.                                                  feedback cycle         */
  159.             }
  160.         weight += delta;    /*   synapse weight corrected by delta      */
  161.         if (weight > MAX_SYNAPSE)
  162.             weight = MAX_SYNAPSE;   /*   limit weight in case of overflow */
  163.         else if (weight < -MAX_SYNAPSE)
  164.             weight = -MAX_SYNAPSE;  /*   limit weight in case of underflow */
  165.                                                                         */
  166.         *synapses++ = (SYNAPSE)weight;  /*   put new weight back in synapse*/
  167.         }
  168. #else                       /* use Megamax inline assembly for Motorola */
  169.     asm
  170.         {
  171.         move.w history(A6), A1;
  172.         A1 = history move.w momentum(A6), D2;
  173.         D2 = momentum move.w error(A6), D3;
  174.         D3 = error move.w#FEEDBACK_SHIFT, D4;
  175.         D4 = shift factorfor feedback move.w#DELTA_SHIFT, D5;
  176.             D5 = shift factorfor delta bra end; 
  177.     loop:; while (--n >= 0)
  178.             ;
  179.         get weight from synapse clr.l D0;
  180.         weight = 0L move.w(synapses), D0;
  181.         weight = *synapse;
  182.         feedback error to inputs move.w D0, D1;
  183.         feedback = weight muls D3, D1;
  184.         feedback *= error asr.l D4, D1;
  185.         feedback >>= FEEDBACK_SHIFT add.w D1, O_ERROR()(inputs);
  186.         inputs->errors += feedback;
  187.         delta proportional to input move.w(inputs), D1;
  188.         delta = inputs->activation adda.l#NEURON_SIZE, inputs;
  189.         inputs++;
  190.         delta proportional to error muls D3, D1;
  191.         delta *= error asr.l D5, D1;
  192.         delta >>= DELTA_SHIFT;
  193.         add momentum to delta cmp.w#0, D2;
  194.         if (0 != momentum)
  195.             beq.s mod;
  196.         add.w(A1), D1;
  197.         delta += *history move.w D1, (A1) + ;
  198.         *history++ = delta;
  199.         modify weight by delta ext.l D1;
  200.         (long)delta
  201.     mod:
  202.         add.l D1,